<template>
  <div ref="threeRef" style="width: 100%; height: 800px; border: 1px solid black"></div>
</template>

<script setup lang="ts">
import * as THREE from 'three';
import { ref, onMounted } from 'vue';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass';
import { Vector2 } from 'three';

const threeRef = ref<HTMLDivElement>();

onMounted(() => {
  const width = threeRef.value.clientWidth;
  const height = threeRef.value.clientHeight;
  console.log('%O', threeRef.value);

  const geometry = new THREE.BoxGeometry(60, 70, 80);

  const material = new THREE.MeshBasicMaterial({ color: 0x11ff00, transparent: true, opacity: 0.5 });

  const sphere = new THREE.Mesh(geometry, material);

  const scene = new THREE.Scene();
  scene.add(sphere);

  const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
  camera.position.set(300, 300, 300);
  camera.lookAt(sphere.position);

  const axesHelper = new THREE.AxesHelper(500);
  scene.add(axesHelper);

  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(width, height);
  renderer.setClearColor(0x444444, 1);
  threeRef.value.appendChild(renderer.domElement);
  renderer.render(scene, camera);

  const controls = new OrbitControls(camera, renderer.domElement);
  controls.addEventListener('change', () => {
    renderer.render(scene, camera);
  });

  const composer = new EffectComposer(renderer);
  const renderPass = new RenderPass(scene, camera);
  const outlinePass = new OutlinePass(new Vector2(width, height), scene, camera);
  //模型描边颜色，默认白色
  outlinePass.visibleEdgeColor.set(0xffff00);
  //高亮发光描边厚度
  outlinePass.edgeThickness = 4;
  //高亮描边发光强度
  outlinePass.edgeStrength = 6;
  //模型闪烁频率控制，默认0不闪烁
  outlinePass.pulsePeriod = 2;
  composer.addPass(renderPass);
  composer.addPass(outlinePass);
  // composer.render();

  renderer.domElement.addEventListener('click', function (event) {
    // .offsetY、.offsetX以canvas画布左上角为坐标原点,单位px
    const px = event.offsetX;
    const py = event.offsetY;
    //屏幕坐标px、py转WebGL标准设备坐标x、y
    //width、height表示canvas画布宽高度
    const x = (px / width) * 2 - 1;
    const y = -(py / height) * 2 + 1;
    //创建一个射线投射器`Raycaster`
    const raycaster = new THREE.Raycaster();
    //.setFromCamera()计算射线投射器`Raycaster`的射线属性.ray
    // 形象点说就是在点击位置创建一条射线，射线穿过的模型代表选中
    raycaster.setFromCamera(new THREE.Vector2(x, y), camera);
    //.intersectObjects([mesh1, mesh2, mesh3])对参数中的网格模型对象进行射线交叉计算
    // 未选中对象返回空数组[],选中一个对象，数组1个元素，选中两个对象，数组两个元素
    const intersects = raycaster.intersectObjects([sphere]);
    console.log('射线器返回的对象', intersects);
    // intersects.length大于0说明，说明选中了模型
    if (intersects.length > 0) {
      // 选中模型的第一个模型，设置为红色
      intersects[0].object.material.color.set(0xff0000);
      intersects[0].object.scale.set(1.2, 1.2, 1.2);
      outlinePass.selectedObjects = [intersects[0].object];
      composer.render();
    }
  });
});

const outlineMesh = () => {};
</script>

<style scoped lang="less"></style>
